package org.toves.checklua.ast;

import java.util.Iterator;
import java.util.NoSuchElementException;

class AstChildren implements Iterator<AstNode>, Iterable<AstNode> {
	private AstNode node;
	private int i;
	private int j;
	private int inext;
	private int jnext;
	
	AstChildren(AstNode node) {
		this.node = node;
		inext = 0; // for the moment set it up so it uses the first parameter
		jnext = 0;
		
		if (node.getParameterCount() > 0 && !parmHasChild(0)) {
			next(); // but if the first parameter doesn't have a node,
		}           // call next to find a parameter that does.
	}
	
	public boolean hasNext() {
		return inext < node.getParameterCount();
	}
	
	public AstNode next() {
		if (!hasNext()) {
			throw new NoSuchElementException();
		}
		
		i = inext;
		j = jnext;
		
		Object parm = node.getParameter(i);
		AstNode ret;
		if (parm instanceof AstNode) {
			ret = (AstNode) parm;
		} else if (parm instanceof AstNode[]) {
			AstNode[] parms = (AstNode[]) parm;
			ret = parms[j];
			if (j + 1 < parms.length) {
				jnext = j + 1;
				return ret;
			}
		} else {
			ret = null; // this won't happen except from constructor
		}
		inext = i + 1;
		jnext = 0;
		while (inext < node.getParameterCount() && !parmHasChild(inext)) {
			inext++;
		}
		return ret;
	}
	
	private boolean parmHasChild(int index) {
		Object parm = node.getParameter(inext);
		if (parm instanceof AstNode) return true;
		if (parm instanceof AstNode[]) return ((AstNode[]) parm).length > 0;
		return false;
	}
	
	public void remove() {
		throw new UnsupportedOperationException("cannot remove children");
	}

	public Iterator<AstNode> iterator() {
		return this;
	}
}
